import datetime

import jwt
from rest_framework.serializers import ModelSerializer

from meiduo.settings import SECRET_KEY
from .models import *
import re
from rest_framework import serializers
from django.core.cache import cache
import redis

r = redis.Redis()


class UserSer(ModelSerializer):

    def validate(self, attrs):

        # 验证code操作
        uuid = attrs.get('uuid')
        # 获取cache中的uuid（验证码）
        # s_code = cache.get(uuid)  # 如果验证码超时 就会返回None
        # 获取redis中的uuid（验证码）
        s_code = r.get(uuid).decode()  # 如果验证码超时 就会返回None
        if not s_code:
            raise serializers.ValidationError('验证码超时')
        # 获取前台传过来的用户输入的验证码
        code = attrs.get('code')
        # 进行验证码比较
        if s_code != code:
            raise serializers.ValidationError('验证码错误')
        return attrs

    # 自定义 单个字段的验证  validate_字段名(self,字段的值)
    def validate_phone(self, value):
        if not re.match(r"^1[356789]\d{9}$", value):
            raise serializers.ValidationError("手机号格式错误")

        # 必须要 返回
        return value

    class Meta:
        model = User
        fields = '__all__'


class LoginSer(ModelSerializer):
    # 防止和model中的username里的unique发生冲突所以重写字段
    username = serializers.CharField(max_length=30)

    def validate(self, attrs):
        # 判断用户是否存在
        user = User.objects.filter(username=attrs.get('username'), password=attrs.get('password')).first()
        # 如果用户存在
        if user:
            # 生成令牌
            data = {
                'exp': datetime.datetime.now() + datetime.timedelta(hours=1),
                'uid': user.id,
                'username': user.username,
            }
            token = jwt.encode(payload=data, key=SECRET_KEY)
            # 把令牌存入到attrs作为验证数据的一部分
            attrs['token'] = token
            attrs['uid'] = user.id
            return attrs
        else:
            raise serializers.ValidationError('用户名或密码错误')

    class Meta:
        model = User
        fields = ['username', 'password']
